﻿using BattleFury.Lib.Collections;
using BattleFury.Lib.Graphics;
using BattleFury.Lib.Maps.Data;
using BattleFury.Maps;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
using System.Linq;

namespace BattleFury.Lib.Maps
{
    public class TileMap : BaseMap
    {
        private readonly List<ILayer> _layers;

        //public string Name { get; set; }
        //public Vector2 Size { get; private set; }
        public Camera Camera { get; set; }

        public List<ILayer> Layers
        {
            get { return _layers; }
        }

        public TileMap(Vector2 size)
        {
            _layers = new List<ILayer>();
            Size = size;
        }

        public override void Update(GameTime gameTime)
        {
            foreach (var layer in _layers)
            {
                layer.Camera = Camera;
                layer.Update(gameTime);
            }
        }

        public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            foreach (var layer in _layers)
            {
                layer.Camera = Camera;
                layer.Draw(gameTime, spriteBatch);
            }
        }

        public void DrawLayer(string layerName, GameTime gameTime, SpriteBatch spriteBatch)
        {
            foreach (var layer in Layers.OfType<TileLayer>().Where(layer => layer.Name == layerName))
            {
                layer.Camera = Camera;
                layer.Draw(gameTime, spriteBatch);
                break;
            }
        }

        public void DrawCollisionLayer(string layerName, GameTime gameTime, SpriteBatch spriteBatch)
        {
            foreach (var layer in Layers.OfType<CollisionLayer>().Where(layer => layer.Name == layerName))
            {
                layer.Camera = Camera;
                layer.Draw(gameTime, spriteBatch);
                break;
            }
        }

        public TileLayer AddTileLayer(Vector2 tileSize)
        {
            var tileLayer = new TileLayer(Size, tileSize);
            _layers.Add(tileLayer);

            return tileLayer;
        }

        public void AddLayer(ILayer layer)
        {
            _layers.Add(layer);
        }

        public static TileMap LoadFrom(TilesetCollection tilesets, TileMapData data)
        {
            var size = new Vector2(data.Width, data.Height);
            var ret = new TileMap(size)
            {
                Name = data.Name
            };

            foreach (var dataLayer in data.Layers)
            {
                if (dataLayer is TileLayerData)
                {
                    var layer = TileLayer.LoadFrom(tilesets, size, dataLayer as TileLayerData);
                    ret.AddLayer(layer);
                }
                if (dataLayer is CollisionLayerData)
                {
                    var layer = CollisionLayer.LoadFrom(size, dataLayer as CollisionLayerData);
                    ret.AddLayer(layer);
                }
            }

            return ret;
        }

        public ILayer GetLayer(string layerName)
        {
            return Layers.FirstOrDefault(l => l.Name == layerName);
        }
    }
}